/*
 * Geopaparazzi - Digital field mapping on Android based devices
 * Copyright (C) 2010  HydroloGIS (www.hydrologis.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package eu.hydrologis.geopaparazzi.maps.overlays;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;

import org.osmdroid.ResourceProxy;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.util.BoundingBoxE6;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.MapView.Projection;
import org.osmdroid.views.overlay.Overlay;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.os.Bundle;

import com.dkeaerospace.egnosdemoapp.GlobalState;

import eu.hydrologis.geopaparazzi.R;
import eu.hydrologis.geopaparazzi.gps.GpsLocation;
import eu.hydrologis.geopaparazzi.util.debug.Debug;
import eu.hydrologis.geopaparazzi.util.debug.Logger;
import eu.hydrologis.geopaparazzi.util.debug.TestMock;

/**
 * Overlay to show the gps position.
 * 
 * @author Andrea Antonello (www.hydrologis.com)
 */
public class GpsPositionOverlay extends Overlay {

    private NumberFormat f = new DecimalFormat("0.00000");
    private NumberFormat f2 = new DecimalFormat("0.0");

    private boolean doDraw = true;

    private Paint gpsPaint = new Paint();
    private Paint egnosPaint = new Paint();
    private Paint recieverPaint = new Paint();
    
    private Paint gpsTextPaint = new Paint();
    private Paint egnosTextPaint = new Paint();
    private Paint recieverTextPaint = new Paint();
    private Paint textPaint = new Paint();

    private final Path gpsPath = new Path();
    private final Path egnospath = new Path();
    private final Path recieverPath = new Path();

    private GpsLocation loc;

    public GpsPositionOverlay( final Context ctx, final ResourceProxy pResourceProxy ) {
        super(pResourceProxy);

        gpsPaint.setAntiAlias(true);
        gpsPaint.setColor(Color.DKGRAY);
        gpsPaint.setStrokeWidth(1f);
        gpsPaint.setStyle(Paint.Style.STROKE);

        egnosPaint.setAntiAlias(true);
        egnosPaint.setColor(Color.BLUE);
        egnosPaint.setStrokeWidth(1f);
        egnosPaint.setStyle(Paint.Style.STROKE);

        recieverPaint.setAntiAlias(true);
        recieverPaint.setColor(Color.RED);
        recieverPaint.setStrokeWidth(1f);
        recieverPaint.setStyle(Paint.Style.STROKE);

        Resources resources = ctx.getResources();
        float textSizeMedium = resources.getDimension(R.dimen.text_normal);
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(textSizeMedium);
        textPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));

        gpsTextPaint.setColor(Color.DKGRAY);
        gpsTextPaint.setAntiAlias(true);
        gpsTextPaint.setTextSize(textSizeMedium);
        gpsTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));

        egnosTextPaint.setColor(Color.BLUE);
        egnosTextPaint.setAntiAlias(true);
        egnosTextPaint.setTextSize(textSizeMedium);
        egnosTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));

        recieverTextPaint.setColor(Color.RED);
        recieverTextPaint.setAntiAlias(true);
        recieverTextPaint.setTextSize(textSizeMedium);
        recieverTextPaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
    }

    public void setDoDraw( boolean doDraw ) {
        this.doDraw = doDraw;
        if (Debug.D)
            Logger.d(this, "Will draw: " + doDraw); //$NON-NLS-1$
    }

    public void setLoc( GpsLocation loc ) {
        this.loc = loc;
    }

    protected void draw( final Canvas canvas, final MapView mapsView, final boolean shadow ) {
        if (loc == null || shadow || !doDraw)
            return;

        Projection pj = mapsView.getProjection();

        Bundle bundle = loc.getExtras();
        double[] coordinates = bundle.getDoubleArray(TestMock.EGNOS_POSITIONS);

        double gpsLatitude = coordinates[0];
        double gpsLongitude = coordinates[1];
        double gpsAltitude = coordinates[2];
        double egnosLatitude = coordinates[3];
        double egnosLongitude = coordinates[4];
        double egnosAltitude = coordinates[5];
        double HPL = coordinates[6];
        double receiverLatitude = coordinates[7];
        double receiverLongitude = coordinates[8];
        double receiverAltitude = coordinates[9];

        GeoPoint gpsPoint = new GeoPoint(gpsLatitude, gpsLongitude);
        Point gpsPixels = pj.toMapPixels(gpsPoint, null);
        // canvas.drawCircle(gpsPixels.x, gpsPixels.y, 1, gpsPaint);
        gpsPath.reset();
        gpsPath.moveTo(gpsPixels.x, gpsPixels.y - 20);
        gpsPath.lineTo(gpsPixels.x, gpsPixels.y + 20);
        gpsPath.moveTo(gpsPixels.x - 20, gpsPixels.y);
        gpsPath.lineTo(gpsPixels.x + 20, gpsPixels.y);
        canvas.drawPath(gpsPath, gpsPaint);

        GeoPoint egnosPoint = new GeoPoint(egnosLatitude, egnosLongitude);
        Point egnosPixels = pj.toMapPixels(egnosPoint, null);
        // canvas.drawCircle(egnosPixels.x, egnosPixels.y, 1, egnosPaint);
        egnospath.reset();
        egnospath.moveTo(egnosPixels.x, egnosPixels.y - 20);
        egnospath.lineTo(egnosPixels.x, egnosPixels.y + 20);
        egnospath.moveTo(egnosPixels.x - 20, egnosPixels.y);
        egnospath.lineTo(egnosPixels.x + 20, egnosPixels.y);
        canvas.drawPath(egnospath, egnosPaint);

        GeoPoint recieverPoint = new GeoPoint(receiverLatitude, receiverLongitude);
        Point recieverPixels = pj.toMapPixels(recieverPoint, null);
        // canvas.drawCircle(sisnetPixels.x, sisnetPixels.y, 1, recieverPaint);
        recieverPath.reset();
        recieverPath.moveTo(recieverPixels.x, recieverPixels.y - 20);
        recieverPath.lineTo(recieverPixels.x, recieverPixels.y + 20);
        recieverPath.moveTo(recieverPixels.x - 20, recieverPixels.y);
        recieverPath.lineTo(recieverPixels.x + 20, recieverPixels.y);
        canvas.drawPath(recieverPath, recieverPaint);

        /*
         * put also text of the elevation
         */

        String gpsElevation = "GPS: " + f.format(gpsLongitude) + "/" + f.format(gpsLatitude) + "/" + f2.format(gpsAltitude);
        String egnosElevation = "EGNOS: " + f.format(egnosLatitude) + "/" + f.format(egnosLongitude) + "/"
                + f2.format(egnosAltitude);
        String sisnetElevation = "Reciev: " + f.format(receiverLatitude) + "/" + f.format(receiverLongitude) + "/"
                + f2.format(receiverAltitude);
        int sisNeT = GlobalState.getSISNeT();
        String sisnetActive = "SISNet active";
        if (sisNeT == 0) {
            sisnetActive = "SISNet NOT active";
        }
        int egnos = GlobalState.getEgnos();
        String egnosActive = "Egnos active";
        if (egnos == 0) {
            egnosActive = "Egnos NOT active";
        }

        IGeoPoint mapCenter = mapsView.getMapCenter();
        Point center = pj.toMapPixels(mapCenter, null);
        BoundingBoxE6 boundingBox = mapsView.getBoundingBox();
        int latNorthE6 = boundingBox.getLatNorthE6();
        int latText = latNorthE6 - 400;

        Point textPoint = pj.toMapPixels(new GeoPoint(latText, mapCenter.getLongitudeE6()), null);

        int upper = textPoint.y;
        int delta = 6;
        Rect rect = new Rect();
        textPaint.getTextBounds(gpsElevation, 0, gpsElevation.length(), rect);
        int textWidth = rect.width();
        int textHeight = rect.height();
        int x = center.x - textWidth / 2;
        canvas.drawText(gpsElevation, x, upper, gpsTextPaint);

        textPaint.getTextBounds(egnosElevation, 0, egnosElevation.length(), rect);
        textWidth = rect.width();
        x = center.x - textWidth / 2;
        canvas.drawText(egnosElevation, x, upper + delta + textHeight, egnosTextPaint);

        textPaint.getTextBounds(sisnetElevation, 0, sisnetElevation.length(), rect);
        textWidth = rect.width();
        x = center.x - textWidth / 2;
        canvas.drawText(sisnetElevation, x, upper + 2 * delta + 2 * textHeight, recieverTextPaint);

        textPaint.getTextBounds(egnosActive, 0, egnosActive.length(), rect);
        textWidth = rect.width();
        x = center.x - textWidth / 2;
        canvas.drawText(egnosActive, x, upper + 3 * delta + 3 * textHeight, textPaint);

        textPaint.getTextBounds(sisnetActive, 0, sisnetActive.length(), rect);
        textWidth = rect.width();
        x = center.x - textWidth / 2;
        canvas.drawText(sisnetActive, x, upper + 4 * delta + 4 * textHeight, textPaint);

        if (TestMock.LOCATIONSENT) {
            Logger.d(this, "*************************************");
            Logger.d(this, "*******    PROCESSING A GPS POSITION");
            String coordsString = Arrays.toString(coordinates);
            Logger.d(this, coordsString);
            Logger.d(this, "*************************************");
            TestMock.LOCATIONSENT = false;
        }
    }

}
